home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Essentials / Developer Essentials May91 / DTS Sample Code / Apple II Sample Code / MPW IIGS SC / SC.005.Custom.Window / rr.window.aii < prev    next >
Encoding:
Text File  |  1990-06-25  |  45.1 KB  |  1,973 lines  |  [TEXT/MPS ]

  1. *******************************************************************************
  2. *
  3. * RoundRect Window
  4. *
  5. * (C)  Copyright Apple Computer, Inc. 1988-1990
  6. * All rights reserved.
  7. *
  8. * Developer Technical Support Apple II Sample Code
  9. *
  10. * by Keith Rollin
  11. *
  12. * This file contains the definition procedure (defProc) for a custom window.
  13. * This window acts like a fairly normal, but limited, window, and has the
  14. * following features:
  15. *
  16. *     - The corners are curved. The radius of the corners can be specified.
  17. *     - It always has a title bar, which always has a solid background color
  18. *       and title in it. The titlebar redraws itself in response to being
  19. *       activated and deactivated.
  20. *     - A GoAway box can optionally be included in the title bar. The zoom
  21. *       box is not drawn or supported.
  22. *     - There are no infobars or frame controls (like scrollbars).
  23. *     - A color table can be provided, or a default color table can be used.
  24. *     - The window can be dragged and grown.
  25. *     - TaskMaster is supported.
  26. *
  27. *******************************************************************************
  28.  
  29.     EJECT
  30. *******************************************************************************
  31. *
  32. RRectDefProcData    RECORD
  33. *
  34. * Description:    Equates and variables used by the RoundRect Window defProc.
  35. *
  36. *
  37. *******************************************************************************
  38.  
  39. ; stack/direct page frame. These equates are used to access information that
  40. ; is passed to the window DefProc on the stack.
  41.  
  42.  
  43.     DefineStack
  44.  
  45. OrigD    word    ; saved Direct Page register
  46. OrigB    byte    ; saved Data Bank register
  47. work    long    ; a LONG of workspace
  48. workRgn    long    ; a LONG of workspace
  49. returnAddr    block 3    ; RTL address
  50. param    long    ; operation specific parameter
  51. theWindow    long    ; This is NOT a pointer to the window.
  52.         ; This is a pointer to a window record.
  53.         ; This means that it points to
  54.         ; owNext, not the grafPort part of
  55.         ; a window record!!
  56. operation    word    ; operation to perform
  57. windGlobals    long    ; pointer to handy values
  58. result    long    ; place to store operation result
  59.  
  60. ;
  61. ; Window Globals table
  62. ;
  63. lineW    equ 0    ; width of vertical lines
  64. titleHeight    equ lineW+2    ; Height of standard title bar
  65. titleYPos    equ titleHeight+2    ; Y offset for title in std. titlebar
  66. closeHeight    equ titleYPos+2    ; height of close icon.
  67. closeWidth    equ closeHeight+2    ; width of close icon.
  68. defWindClr    equ closeWidth+2    ; pointer to default color table
  69. windIconFont    equ defWindClr+4    ; handle to current window icon font
  70. screenMode    equ windIconFont+4    ; TRUE if 640 mode, FALSE if 320
  71. pattern    equ screenMode+2    ; Temporary pattern buffer
  72. callerDPage    equ pattern+32    ; DP of last caller to TaskMaster
  73. callerDataB    equ callerDPage+2    ; DBR of last caller to TaskMaster
  74.  
  75. ;
  76. ; NewWindow Parameter list
  77. ;
  78.     DSect 0
  79. wParamID    word    ; should be zero for custom windows
  80. wMe    long    ; address of customProc
  81. wFrameBits    word    ; flags that determine window type
  82. wPosition    block 8    ; used as portRect for contents
  83. wPlane    long    ; window Plane
  84. wStorage    long    ; storage for the window record
  85. ; These 2 are copied in one pass. Keep together and in this order.
  86. wRefCon    long    ; refCon
  87. wContDraw    long    ; routine that draw the contents
  88. ; Everything past here is copied after the wFrame field of the Window Record.
  89. wCustom    block 0    ; start of custom information section
  90. wTitle    long    ; pointer to window's title
  91. wColorTable    long    ; pointer to color table
  92. wRV    word    ; vertical radius of corners
  93. wRH    word    ; horizontal radius of corners
  94. wEnd    block 0
  95.  
  96. ;
  97. ; My extensions for this custom window
  98. ;
  99.     DSect windSize
  100. xowTitle    long    ; pointer to window's title
  101. xowColorPtr    long    ; pointer to our color table (if any)
  102. xowRV    word    ; vertical radius of corners
  103. xowRH    word    ; horizontal radius of corners
  104. xowEnd    block 0
  105.  
  106. ;
  107. ; Position of the GoAway box
  108. ;
  109. GAX    equ 10
  110. GAY    equ 2
  111.  
  112. ;
  113. ; Scratch areas
  114. ;
  115. contRect    ds.b 8
  116. strucRect    ds.b 8
  117. pRect    ds.b 8
  118.  
  119.     ENDR
  120.  
  121.  
  122.     EJECT
  123. *******************************************************************************
  124. *
  125. RRectDefProc    PROC
  126. *
  127. * Description:    Main Procedure for the RoundRect custom window definition.
  128. *    This routine creates a suitable environment for us (saves
  129. *    the old Direct Page and Data Bank registers and makes us
  130. *    some new ones), calls the appropriate routine based on
  131. *    the value of 'operation', and returns to the Window
  132. *    Manager with the Carry bit and Y register set correctly.
  133. *
  134. *
  135. * Inputs:
  136. *    On entry, the stack contains the following values:
  137. *
  138. *    -------- previous contents --------
  139. *    LONG  result    space for result
  140. *    LONG  windGlobals    pointer to WMgr globals
  141. *    WORD  operation    operation number to be performed
  142. *    LONG  theWindow    ptr to window's record
  143. *    LONG  param    additional parameter for some ops.
  144. *    3 Bytes    RTL Address
  145. *          <------------ Stack Pointer
  146. *
  147. * Outputs:    Carry = clear if no error
  148. *    Carry = set if error, and Y has error number.
  149. *
  150. * External Refs:
  151.     import rrDraw
  152.     import rrHit
  153.     import rrCalcRgns
  154.     import rrNew
  155.     import rrDispose
  156.     import rrGetDrag
  157.     import rrGrowFrame
  158.     import rrRecSize
  159.     import rrPosition
  160.     import rrBehind
  161.     import rrCallDefProc
  162. *
  163. * Entry Points:    NONE
  164. *
  165. *******************************************************************************
  166.     with RRectDefProcData
  167. wMaxTask    equ 10
  168.  
  169. ; The first thing we do is get a little Direct Page space by using the stack.
  170. ; First, push on some scratch space onto the stack, then save the old values
  171. ; of the Data Bank Register and the Direct Page Register. Set the Data Bank
  172. ; Register to the same value as the Program Bank Register, and then transfer
  173. ; the Stack Pointer to the Direct Page Register. This gives us a stack and
  174. ; Direct Page that looks like this:
  175. ;
  176. ; Direct Page location  SIZE  What it is
  177. ;    25  LONG  result
  178. ;    21  LONG  windGlobals
  179. ;    19  WORD  operation
  180. ;    15  LONG  theWindow
  181. ;    11  LONG  param
  182. ;     8  3 Bytes RTL Address
  183. ;     4  LONG  workspace
  184. ;     3  BYTE  old Data Bank Register
  185. ;     1  WORD  old Direct Page Register
  186. ;            <--- stack pointer
  187.  
  188.     pha    ; Push on 8 bytes of workspace.
  189.     pha
  190.     pha
  191.     pha
  192.  
  193.     phb    ; Save the data bank register
  194.     phd    ; Save the direct page register
  195.  
  196. ; Set the Data Bank register to the Program Bank register. This allows short
  197. ; (2 byte) addressing, as opposed to the 3 byte addressing we would have had
  198. ; to use if the Data Bank register were set to some unknown value.
  199.  
  200.     phk    ; Set up my own DBR
  201.     plb
  202.  
  203. ; Set the direct page to the stack. This lets us use some of the values passed
  204. ; to us as 'zero-page' pointers (like theWindow).
  205.  
  206.     tsc    ; Set up my own Direct Page
  207.     tcd
  208.  
  209. ; Zero out 'result' as default.
  210.  
  211. @a    stz <result    ; zero this out to start with
  212.     stz <result+2
  213.  
  214. ; Find out which operation to perform, check its range, and, if it is OK,
  215. ; convert it to an index into a jump table. Execute the routine.
  216.  
  217.     lda <operation
  218.     cmp #wMaxTask+1
  219.     bcs OutOfRange
  220.  
  221.     asl a
  222.     tax
  223.     jsr (opTable,x)
  224.  
  225. ; The operation has been carried out. Strip the parameters off of the stack
  226. ; and move the return address up, making sure to leave the 'result'. Gotta be
  227. ; careful to preserve the carry flag here!!!
  228.  
  229. OutOfRange    lda <returnAddr    ; move the return address up
  230.     sta <result-3
  231.     lda <returnAddr+1
  232.     sta <result-2
  233.  
  234.     tsc    ; get the stack ptr so we can change it
  235.  
  236.     pld    ; restore the DP and DBR
  237.     plb
  238.  
  239.     php    ; save the state of the carry
  240.     clc    ; fudge the stack pointer
  241.     adc #result-4
  242.     plp    ; restore the carry state
  243.     tcs    ; point the stack pointer to the return
  244.         ; address we moved up
  245.  
  246.     rtl    ; back to the window manager
  247.  
  248. opTable    dc.w rrDraw    ; Draw the specified part
  249.     dc.w rrHit    ; determine where we hit
  250.     dc.w rrCalcRgns    ; Calculate Struc and Content Regions
  251.     dc.w rrNew    ; Perform initialization
  252.     dc.w rrDispose    ; Close window
  253.     dc.w rrGetDrag    ; Dragging to be done
  254.     dc.w rrGrowFrame    ; Grow the frame
  255.     dc.w rrRecSize    ; Return our window record size
  256.     dc.w rrPosition    ; Return window pos/size
  257.     dc.w rrBehind    ; Return plane placement
  258.     dc.w rrCallDefProc    ; Perform special stuff
  259.  
  260.     ENDP
  261.  
  262.     EJECT
  263. *******************************************************************************
  264. *
  265. rrDraw    PROC
  266. *
  267. * Description:    Draw the specified part of the window.
  268. *
  269. * We draw the window frame (part $0000) in the following way:
  270. *
  271. *   1. Save various QuickDraw states that we will be changing.
  272. *   2. Set the pen to normal.
  273. *   3. Get the rectangle of our structure region.
  274. *   4. Get a pointer to the color table we'll be using.
  275. *   5. Set the color of the title bar (background). This changes
  276. *      depending on whether the window is active or not.
  277. *   6. Draw the title bar with PaintRect.
  278. *   7. Set the color to the outline color.
  279. *   8. Draw the main part of the frame with FrameRRect.
  280. *   9. Draw the line that divides the title bar from the content region.
  281. *  10. Calculate and position the pen for the string title.
  282. *  11. Set the color for the title. Again, this changes depending on
  283. *      whether the window is active or not.
  284. *  12. If the window is active, call the standalone routine that draws
  285. *      the close box (part $0001).
  286. *  13. Restore the QuickDraw state we saved and return.
  287. *
  288. *
  289. * Inputs:    param  = specification of part to draw:
  290. *
  291. *         0 = draw the entire window
  292. *         1 = draw the go-away region
  293. *         2 = draw the zoom region
  294. *         3 = draw the info bar
  295. *
  296. *    If the high bit of param is set, then draw the item in
  297. *    its highlighted state. Note: to determine whether to draw
  298. *    a window titlebar in its active or inactive state, look
  299. *    at the fHilite flag in the window record.
  300. *
  301. * Outputs:    result = zero
  302. *    carry  = clear
  303. *
  304. * External Refs:    NONE
  305. *
  306. * Entry Points:
  307.     entry drawFrame    ; called by rrSetxxxx routines when a
  308.         ; field is changed.
  309. *
  310. *******************************************************************************
  311.     with RRectDefProcData
  312.  
  313.     lda <param    ; find out which part to draw
  314.     asl a    ; turn into an index into a jump table
  315.     tax
  316.     jsr (partToDraw,x)
  317.  
  318.     clc
  319.     rts
  320.  
  321. partToDraw    dc.w drawFrame
  322.     dc.w drawGoAway
  323.     dc.w drawZoomBox
  324.     dc.w drawInfoBar
  325.  
  326. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  327. ;
  328. ; Draws the entire frame of a window. This includes the go-away box and any
  329. ; other parts of the frame that you may implement (like a zoom box, an
  330. ; infobar, scrollbars, grow box, etc.
  331. ;
  332. drawFrame    pha    ; save the text mode (on the stack!)
  333.     _GetTextMode
  334.  
  335.     pha
  336.     _GetPenMode
  337.  
  338.     pha    ; and the color (on the stack!)
  339.     _GetForeColor
  340.  
  341.     _PenNormal
  342.  
  343.     jsr GetStrucRect
  344.  
  345.     jsr SetColorTable    ; put ptr to a color table into 'work'
  346.  
  347. ;
  348. ; Now draw the background of the window. Set the color to the backbround color
  349. ; in the color table, then do a PaintRect to draw it all.
  350. ;
  351.     jsr SetBGColor
  352.  
  353.     ldy #6    ;Make a local rectangle that
  354. @a    lda strucRect,y    ;encompasses the title bar.
  355.     sta pRect,y
  356.     dey
  357.     dey
  358.     bpl @a
  359.     ldy #titleHeight
  360.     clc
  361.     adc [<windGlobals],y
  362.     dec a
  363.     sta pRect+4
  364.     inc pRect
  365.  
  366.     pha    ;Make a rectangular region the
  367.     pha    ;same size as this rectangle.
  368.     _NewRgn
  369.     lda 1,s
  370.     sta <workRgn
  371.     lda 3,s
  372.     sta <workRgn+2
  373.     pea pRect>>16
  374.     pea pRect
  375.     _RectRgn
  376.  
  377.     stz offset
  378.     stz offset+2
  379.     PushLong #offset
  380.     _LocalToGlobal
  381.     pei <workRgn+2
  382.     pei <workRgn
  383.     lda offset+2
  384.     pha
  385.     lda offset
  386.     pha
  387.     _OffsetRgn
  388.  
  389.     ldy #owStrucRgn+2    ; get the handle from the window record
  390.     lda [<theWindow],y
  391.     pha
  392.     dey
  393.     dey
  394.     lda [<theWindow],y
  395.     pha
  396.     pei <workRgn+2
  397.     pei <workRgn
  398.     pei <workRgn+2
  399.     pei <workRgn
  400.     _SectRgn
  401.  
  402.     stz offset
  403.     stz offset+2
  404.     PushLong #offset
  405.     _GlobalToLocal
  406.     pei <workRgn+2
  407.     pei <workRgn
  408.     lda offset+2
  409.     pha
  410.     lda offset
  411.     pha
  412.     _OffsetRgn
  413.  
  414.     pei <workRgn+2
  415.     pei <workRgn
  416.     pea 2
  417.     pea 0
  418.     _InsetRgn
  419.  
  420.     pei <workRgn+2
  421.     pei <workRgn
  422.     _PaintRgn
  423.  
  424. ;
  425. ; Draw the frame. Set the outline color and the Pen Width, and use
  426. ; 'strucRect' to call FrameRRect.
  427. ;
  428.  
  429.     ldy #oframeColor    ; set the outline color
  430.     lda [<work],y    ; in bits 7-4
  431.     lsr a
  432.     lsr a
  433.     lsr a
  434.     lsr a
  435.     and #%00001111
  436.     pha
  437.     _SetSolidPenPat
  438.  
  439.     ldy #lineW    ; now set up the pen size by using the
  440.     lda [<windGlobals],y ; pen width value the Window Manager
  441.     pha    ; passes to us in the Globals section.
  442.     PushWord #1    ; hardcode the height to 1
  443.     _SetPenSize
  444.  
  445.     PushLong #strucRect    ; now draw the entire frame
  446.     ldy #xowRH    ; these are the radii of the corners
  447.     lda [<theWindow],y
  448.     pha
  449.     ldy #xowRV
  450.     lda [<theWindow],y
  451.     pha
  452.     _FrameRRect
  453.  
  454.     lda strucRect    ; calculate the VPos of the dividing
  455.     ldy #titleHeight    ; line.
  456.     clc
  457.     adc [<windGlobals],y
  458.     dec a
  459.  
  460.     ldx strucRect+6    ; push on first X/Y coordinate of a
  461.     dex    ; moveTo/lineTo sequence
  462.     dex
  463.     phx
  464.     pha
  465.  
  466.     ldx strucRect+2    ; the other X/Y coordinate
  467.     phx
  468.     pha
  469.  
  470.     _MoveTo    ; draw the dividing line
  471.     _LineTo
  472.  
  473. ; Position and draw the title. Use 'oTitleColor' in the color table.
  474.  
  475.     jsr GetStringXPos
  476.  
  477.     PushWord XPos    ; Next position to draw the title
  478.     ldy #titleYPos    ; let the window manager tell us its
  479.     PushWord [<windGlobals],y ; vertical position.
  480.     _Moveto
  481.  
  482.     PushWord #modeForeCopy ; set mode to our liking
  483.     _SetTextMode
  484.  
  485.     jsr SetTitleColor    ; set up colors accordingly
  486.  
  487.     PushLong TitlePtr    ; draw the title
  488.     _DrawString
  489.  
  490.     jsr WindowActive    ; Is the window active? If so
  491.     beq noGoAway    ; don't grow goAway box
  492.  
  493.     ldy #owFrame    ; does this window have a close
  494.     lda [<theWindow],y    ; box?
  495.     and #fClose
  496.     beq noGoAway    ; no so don't draw one.
  497.  
  498.     jsr drawGoAway
  499.  
  500. noGoAway
  501.     _SetForeColor    ; restore the color and the mode
  502.     _SetPenMode
  503.     _SetTextMode
  504.  
  505.     rts
  506.  
  507. offset    ds.w 2
  508.  
  509. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  510. ;
  511. ; Draw JUST the go-away box in the frame. This will ususally be called when
  512. ; TrakGoAway needs to (un)hilite it, but it could really be called at any
  513. ; time.
  514.  
  515. drawGoAway
  516.     jsr SetColorTable    ; get a pointer to color table
  517.  
  518.     pha    ; save the text mode (on the stack!)
  519.     _GetTextMode
  520.  
  521.     pha    ; and the color (on the stack!)
  522.     _GetForeColor
  523.  
  524.     pha    ; and the color (on the stack!)
  525.     _GetBackColor
  526.  
  527.     PushWord #modeCopy    ; set mode to our liking
  528.     _SetTextMode
  529.  
  530.     ldy #otitleColor    ; set the text color
  531.     lda [<work],y
  532.     and #%00001111
  533.     pha
  534.     _SetForeColor
  535.  
  536.     ldy #otBarColor    ; set the background
  537.     lda [<work],y
  538.     and #%00001111
  539.     pha
  540.     _SetBackColor
  541.  
  542.     pha    ; save the current font so that we
  543.     pha    ; can switch to the Window Manager
  544.     _GetFont    ; icon font.
  545.     PullLong OldFont
  546.  
  547.     ldy #windIconFont+2    ; Get the Window icons from the
  548.     PushWord [<windGlobals],y ; window globals area
  549.     dey
  550.     dey
  551.     PushWord [<windGlobals],y
  552.     _SetFont
  553.  
  554.     PushWord #GAX    ; X position for goaway
  555.     PushWord #GAY    ; Y ditto
  556.     _MoveTo
  557.  
  558.     lda <param+2    ; how are we to draw this?
  559.     bmi DrawHilited
  560.  
  561.     PushWord #0    ; draw a normal go-away box
  562.     bra DrawIt
  563. DrawHilited    PushWord #1    ; draw a hilited go-away box
  564. DrawIt    _DrawChar
  565.  
  566.     PushLong OldFont    ; put the old font back
  567.     _SetFont
  568.  
  569.     _SetBackColor    ; restore the mode and color
  570.     _SetForeColor    ; restore the mode and color
  571.     _SetTextMode
  572.  
  573.     rts
  574.  
  575. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  576. ;
  577. ; These aren't implemented.
  578.  
  579. drawZoomBox
  580. drawInfoBar
  581.     rts
  582.  
  583. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  584. ;
  585. ; Utility routines for DrawFrame
  586. ;
  587. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  588. ;
  589. ; Check the window record to see if there is a pointer to a
  590. ; color table there. If there is one, put it into 'work' for
  591. ; later use. If there isn't one, use the default provided us
  592. ; by the Window Manager in WindGlobals.
  593. ;
  594.  
  595. SetColorTable
  596.     ldy #xowColorPtr    ; set what is pointed to in the
  597.     lda [<theWindow],y    ; window record. Store it into
  598.     sta <work    ; 'work' assuming that it is not
  599.     iny    ; zero.
  600.     iny
  601.     lda [<theWindow],y
  602.     sta <work+2
  603.     ora <work    ; is it really zero?
  604.     bne done    ; no, so use it.
  605.  
  606.     ldy #defWindClr    ; yes, it is zero. Use the defaults.
  607.     lda [<windGlobals],y
  608.     sta <work
  609.     iny
  610.     iny
  611.     lda [<windGlobals],y
  612.     sta <work+2
  613. done
  614.     rts
  615.  
  616.  
  617. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  618. ;
  619. ; Do some math to determine where the title string will go. We use
  620. ; the formula: (midpoint of the window) - (half the length of the string)
  621. ;
  622. ;     (left + (right - left) / 2)) - (StringWidth) / 2
  623. ;
  624. ; which reduces to:
  625. ;
  626. ;     (left + right - StringWidth) / 2
  627. ;
  628.  
  629. GetStringXPos
  630.     ldy #xowTitle+2    ; get the offset in the record to the
  631.     lda [<theWindow],y    ; title
  632.     sta TitlePtr+2
  633.     dey
  634.     dey
  635.     lda [<theWindow],y
  636.     sta TitlePtr
  637.  
  638.     pha    ; find out how long it is to center it
  639.     PushLong TitlePtr
  640.     _StringWidth
  641.     PullWord XPos    ; save it here for a little bit
  642. ;
  643. ; now find the left edge of the string by using the equation:
  644. ;  (windLeft+windRight-strLen)/2
  645. ;
  646.     ldy #oport+oportRect+6 ; get the right edge of the window
  647.     lda [<theWindow],y
  648.     dey
  649.     dey
  650.     dey
  651.     dey
  652.     clc
  653.     adc [<theWindow],y    ; add the right edge
  654.     sec
  655.     sbc XPos    ; subtract the string's width
  656.     lsr a    ; divide it all by two
  657.     sta XPos    ; save the left edge starting position
  658.     rts
  659.  
  660.  
  661.  
  662. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  663. ;
  664. ; Get the boundsRect of the StrucRgn in the window record. This allows us
  665. ; to do a simple FrameRRect(portRect), which is a lot faster for drawing
  666. ; the frame than FrameRgn(strucRgn).
  667.  
  668.     Entry GetStrucRect    ; also called from myDragRoutine
  669. GetStrucRect
  670.     ldy #owStrucRgn    ; get the handle from the window record
  671.     lda [<theWindow],y
  672.     sta <work
  673.     iny
  674.     iny
  675.     lda [<theWindow],y
  676.     sta <work+2
  677.  
  678.     ldy #2    ; now dereference into a pointer
  679.     lda [<work],y
  680.     tax
  681.     lda [<work]
  682.     sta <work
  683.     stx <work+2
  684.  
  685.     ldy #2+6    ; copy the rgnBBox into pRect
  686.     ldx #6
  687. loop
  688.     lda [<work],y
  689.     sta strucRect,x
  690.     dey
  691.     dey
  692.     dex
  693.     dex
  694.     bpl loop
  695.  
  696.     PushLong #strucRect
  697.     _GlobalToLocal
  698.  
  699.     PushLong #strucRect+4
  700.     _GlobalToLocal
  701.     rts
  702.  
  703. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  704. ;
  705. ; Find the state of the window (whether it's active or not), and set
  706. ; the BackGround color of the Title bar accordingly. These colors are
  707. ; obtained from the color table pointed to by 'work'.
  708.  
  709. SetBGColor
  710.     jsr WindowActive    ; drawing an inactive window?
  711.     beq Inact1    ; yes, set the right color
  712.  
  713.     ldy #otBarColor    ; set the background color
  714.     lda [<work],y
  715.     and #%00001111    ; in bits 3-0
  716.     pha
  717.     bra SetIt1
  718.  
  719. Inact1
  720.     ldy #otitleColor    ; set the background color
  721.     lda [<work],y
  722.     xba    ; in bits 11-8
  723.     and #%00001111
  724.     pha
  725.  
  726. SetIt1
  727.     _SetSolidPenPat
  728.     rts
  729.  
  730.  
  731. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  732. ;
  733. ; We are about to draw the title in the title bar. This routine gets
  734. ; and sets the color for that based on the entry in the color table
  735. ; pointed to by 'work'.
  736.  
  737. SetTitleColor
  738.     jsr WindowActive    ; is this an inactive window?
  739.     beq Inact2    ; yes
  740.  
  741.     ldy #otitleColor    ; set the text color
  742.     lda [<work],y
  743.     and #%00001111    ; in bits 3-0
  744.     pha
  745.     bra SetIt2
  746.  
  747. Inact2
  748.     ldy #otitleColor    ; set the text color
  749.     lda [<work],y
  750.     lsr a    ; in bits 7-4
  751.     lsr a
  752.     lsr a
  753.     lsr a
  754.     and #%00001111
  755.     pha
  756.  
  757. SetIt2
  758.     _SetForeColor
  759.     rts
  760.  
  761.  
  762. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  763. ;
  764. ; Short utility routine that returns z=1 if the window is active
  765. ; and z=0 if not.
  766. ;
  767.  
  768. WindowActive
  769.     ldy #owFrame
  770.     lda [<theWindow],y
  771.     and #fHilited    ; return z=1 if active window
  772.     rts
  773.  
  774. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  775. ;
  776. ; Local Data Storage
  777. ;
  778.  
  779. TitlePtr    ds.b 4
  780. XPos    ds.b 2
  781. OldFont    ds.b 4    ; holds old font when we switch to
  782.         ; the Window Manager font
  783.     ENDP
  784.  
  785.     EJECT
  786. *******************************************************************************
  787. *
  788. rrHit    PROC
  789. *
  790. * Description:    Test to see which part of the window was hit (if any).
  791. *
  792. *
  793. * Inputs:    param  = point to test
  794. *         bits 0-15 = Y-coord;
  795. *         bits 16-31 = X-coord.
  796. *        (in local coordinates)
  797. *
  798. * Outputs:    result =  0 wNoHit       Not on the window at all
  799. *             20 wInDrag      in Drag bar region
  800. *            *21 wInGrow      in Grow region
  801. *             22 wInGoAway    in Go-away region
  802. *             *23 wInZoom      in Zoom region
  803. *            *24 wInInfo      in Info bar
  804. *             27 wInFrame     in the window, but none of above
  805. *    carry  = clear
  806. *    (Result numbers with an asterisk (*) next to them are
  807. *     not supported in this window)
  808. *
  809. * External Refs:    NONE
  810. *
  811. * Entry Points:    NONE
  812. *
  813. *******************************************************************************
  814.     with RRectDefProcData
  815.  
  816.     lda <param    ; Make a copy of this so that it will
  817.     sta myLocalPoint    ; be easier push its address onto the
  818.     lda <param+2    ; stack.
  819.     sta myLocalPoint+2
  820.  
  821.     PushLong #myLocalPoint
  822.     _LocalToGlobal
  823.  
  824. ; Check to see if the mouse was clicked in the strucRgn, which is also
  825. ; in global coordinates.
  826.  
  827.     pha    ; room for result
  828.     PushLong #myLocalPoint ; push a pointer to the point
  829.     ldy #owStrucRgn+2    ; push on strucRgn from theWindow
  830.     lda [<theWindow],y
  831.     pha
  832.     dey
  833.     dey
  834.     lda [<theWindow],y
  835.     pha
  836.     _PtInRgn
  837.     pla    ; did we hit the strucRgn?
  838.     beq done    ; no, return no hit
  839.  
  840.     jsr ckGoAway    ; did we hit the goaway box?
  841.     bne done    ; if so, it returns wInGoAway
  842.  
  843.     ldy #owFrame    ; is the window draggable?
  844.     lda [<theWindow],y
  845.     and #fMove
  846.     beq notDraggable    ; no, return wInFrame part
  847.  
  848.     lda <param    ; load in the Y coordinate
  849.     ldy #titleHeight
  850.     cmp [<windGlobals],y ; is it in the title region
  851.     bge notDraggable    ; no, so return wInFrame.
  852.  
  853.     lda #wInDrag    ; return wInDrag
  854.     bra done
  855.  
  856. notDraggable
  857.     lda #wInFrame    ; fall to exit routine
  858.  
  859. done
  860.     sta <result
  861.     clc
  862.     rts
  863.  
  864. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  865. ;
  866. ckGoAway
  867. ;
  868. ; See if the mouse button was clicked while the cursor was in the
  869. ; goaway box. We simply use PtInRect for this.
  870. ;
  871. ; The window must both be active and have a close box in order for
  872. ; us to return a 'wInGoAway' condition.
  873. ;
  874.  
  875.     ldy #owFrame    ; Check for these conditions in
  876.     lda [<theWindow],y    ; one blow. If both bits are set,
  877.     and #fHilited+fClose ; then check to see if we landed in
  878.     cmp #fHilited+fClose ; the close box. If both are not
  879.     bne notInGoAway    ; set, then leave.
  880.  
  881.     ldy #closeHeight    ; calculate the dimensions of the
  882.     lda [<windGlobals],y ; goAway box.
  883.     clc
  884.     adc goAwayRect
  885.     sta goAwayRect+4
  886.     ldy #closeWidth
  887.     lda [<windGlobals],y
  888.     clc
  889.     adc goAwayRect+2
  890.     sta goAwayRect+6
  891.  
  892.     lda <param    ; we need this back in global
  893.     sta myLocalPoint    ; coordinates
  894.     lda <param+2
  895.     sta myLocalPoint+2
  896.  
  897.     pha    ; room for result
  898.     PushLong #myLocalPoint ; check the mouse click
  899.     PushLong #goAwayRect
  900.     _PtInRect
  901.     pla
  902.     beq notInGoAway    ; not there, return zero
  903.     lda #wInGoAway    ; hit close box, return wInGoAway
  904.     bra doneGoAway
  905.  
  906. notInGoAway
  907.     lda #wNoHit
  908. doneGoAway
  909.     rts
  910.  
  911. myLocalPoint    ds.b 4
  912. goAwayRect    dc.w GAY,GAX,0,0
  913.  
  914.     ENDP
  915.  
  916.     EJECT
  917. *******************************************************************************
  918. *
  919. rrCalcRgns    PROC
  920. *
  921. * Description:    Calculate the content and structure regions of the window
  922. *    in Global coordinates.
  923. *
  924. *
  925. * Inputs:    theWindow's portRect and boundsRect will be set
  926. *    appropriately. NOTE: The strucRgn and contRgn must be
  927. *    returned in GLOBAL coordinates. However, while the
  928. *    settings of the portRect and boundsRect show the relative
  929. *    positioning of the window on the desktop, they do not give
  930. *    a rectangle in global coordinates on which we can base our
  931. *    calculations. The routine "GetpRect" shows the correct way
  932. *    to get a rectangle in global coordinates on which you
  933. *    should base your calculations.
  934. *
  935. * Outputs:    result =  0
  936. *    carry  = clear
  937. *    theWindow.StrucRgn = frame region
  938. *        (region handle already allocated)
  939. *    theWindow.ContRgn = content region
  940. *        (region handle already allocated)
  941. *
  942. * External Refs:    NONE
  943. *
  944. * Entry Points:    NONE
  945. *
  946. *******************************************************************************
  947.     with RRectDefProcData
  948.  
  949.     jsr GetpRect    ; get portRect; convert to Globals
  950. ;
  951. ; Create the rectangle we will use for creating the strucRgn. This is
  952. ; calculated based on the portRect, titleHeight, and screen mode.
  953. ;
  954.     ldy #titleHeight    ; Get the suggested height of titlebar
  955.     lda contRect    ; Raise the height of the strucRect by
  956.     sec    ;    that much.
  957.     sbc [<windGlobals],y
  958.     sta strucRect
  959.  
  960.     lda contRect+4    ; lower bottom of the strucRect by 1
  961.     ina
  962.     sta strucRect+4
  963.  
  964.     ldy #lineW    ; adjust width of the strucRect based
  965.     lda contRect+2    ; on the size of the lineWidth
  966.     sec
  967.     sbc [<windGlobals],y ; one linewidth on the left...
  968.     sta strucRect+2
  969.  
  970.     lda contRect+6
  971.     clc
  972.     adc [<windGlobals],y ; ...and on the right.
  973.     sta strucRect+6
  974.  
  975. ; now create the Content Region by doing a FrameRRect on the contRect, and
  976. ; adding a square region to it. First create a round rect region of the full
  977. ; content size.
  978.  
  979.     _OpenRgn
  980.  
  981.     PushLong #contRect
  982.     ldy #xowRH    ; these are the radii of the corners
  983.     PushWord [<theWindow],y
  984.     ldy #xowRV
  985.     PushWord [<theWindow],y
  986.     _FrameRRect
  987.  
  988.     ldy #owContRgn+2    ; push on the handle of the content
  989.     lda [<theWindow],y    ; region stored in the window record
  990.     sta ContRgnHandle+2
  991.     pha
  992.     dey
  993.     dey
  994.     lda [<theWindow],y
  995.     sta ContRgnHandle
  996.     pha
  997.     _CloseRgn
  998.  
  999. ; Now create a square region to fill in the small upper corners.
  1000.  
  1001.     pha
  1002.     pha
  1003.     _NewRgn
  1004.     PullLong TempRgn
  1005.  
  1006.     lda contRect
  1007.     clc
  1008.     ldy #xowRV
  1009.     adc [<theWindow],y
  1010.     sta contRect+4
  1011.  
  1012.     PushLong TempRgn
  1013.     PushLong #contRect
  1014.     _RectRgn
  1015.  
  1016. ; Add the two regions together.
  1017.  
  1018.     PushLong ContRgnHandle
  1019.     PushLong TempRgn
  1020.     PushLong ContRgnHandle
  1021.     _UnionRgn
  1022.  
  1023.     PushLong TempRgn
  1024.     _DisposeRgn
  1025.  
  1026. ; now create the Structure Region by doing a FrameRRect on the strucRect.
  1027.  
  1028.     _OpenRgn
  1029.  
  1030.     PushLong #strucRect
  1031.     ldy #xowRH    ; these are the radii of the corners
  1032.     PushWord [<theWindow],y
  1033.     ldy #xowRV
  1034.     PushWord [<theWindow],y
  1035.     _FrameRRect
  1036.  
  1037.     ldy #owStrucRgn+2    ; push on the handle of the structure
  1038.     lda [<theWindow],y    ; region stored in the window record.
  1039.     sta StrucRgnHandle+2
  1040.     pha
  1041.     dey
  1042.     dey
  1043.     lda [<theWindow],y
  1044.     sta StrucRgnHandle
  1045.     pha
  1046.     _CloseRgn
  1047.  
  1048.     clc
  1049.     rts
  1050.  
  1051. ContRgnHandle    ds.b 4
  1052. StrucRgnHandle    ds.b 4
  1053. TempRgn    ds.b 4
  1054.  
  1055. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1056. ;
  1057. ; Fetches the portrect from the window record, and converts it to
  1058. ; global coordinates. It leaves the rectangle in 'pRect' and 'contRect'
  1059. ;
  1060. ; LocalToGlobal conversion is done by subtracting boundsRect.y1 from the
  1061. ; vertical coordinates of portRect, and doing similarly for the horizontal
  1062. ; coordinates. This is essentially saying "How far away from the top and
  1063. ; left edges of the screen is the portRect?".
  1064. ;
  1065.  
  1066. GetpRect    ldy #oport+oboundsRect
  1067.     lda [<theWindow],y    ;Get the boundsRect y1,x1 and save it in a way
  1068.     sta @toglobal    ;that allows us to use it conveniently.
  1069.     sta @toglobal+4
  1070.     iny
  1071.     iny
  1072.     lda [<theWindow],y
  1073.     sta @toglobal+2
  1074.     sta @toglobal+6
  1075.  
  1076.     ldy #oport+oportRect+6
  1077.     ldx #6    ;Globalize the portRect and save it where
  1078. @a    lda [<theWindow],y    ;"others" can get it.
  1079.     sec
  1080.     sbc @toglobal,x
  1081.     sta pRect,x
  1082.     sta contRect,x
  1083.     dey
  1084.     dey
  1085.     dex
  1086.     dex
  1087.     bpl @a
  1088.  
  1089.     rts
  1090.  
  1091. @toglobal    ds.b    8
  1092.  
  1093.     ENDP
  1094.  
  1095.     EJECT
  1096. *******************************************************************************
  1097. *
  1098. rrNew    PROC
  1099. *
  1100. * Description:
  1101. *
  1102. * Perform any window record initialization. This routine is should set :
  1103. *
  1104. *   - the wRefCon, wContDraw, wColors, and wFrameCtls fields.
  1105. *   - the fCtlTie, fVis, and fQContent bits in wFrame word.
  1106. *   - any other fields in the Custom part of the record.
  1107. *
  1108. * The following has already been done:
  1109. *
  1110. *   - a window record has been allocated (as specified by the wNew call).
  1111. *   - a port has been opened (as specified by the wPosition call).
  1112. *   - handles have been placed in wStrucRgn, wContRgn, and wUpdateRgn.
  1113. *   - wContDefProc points to us.
  1114. *   - the window has been added to the window list, and wNext field set.
  1115. *   - the fAllocated and fHilited bits have been set. All others are zero.
  1116. *
  1117. * Here is the window record. Asterisks are by the fields we have to set up:
  1118. *
  1119. *      -4 owNext
  1120. *       0 owPort
  1121. *     170 owDefProc
  1122. *    *174 owrRefCon
  1123. *    *178 owContDraw
  1124. *     182 owReserved
  1125. *     186 owStrucRgn
  1126. *     190 owContRgn
  1127. *     194 owUpdateRgn
  1128. *     198 owCtls
  1129. *    *202 owFrameCtls
  1130. *    *206 owFrame
  1131. *    *208 owCustom
  1132. *
  1133. *
  1134. * Inputs:    param  = pointer to parameter list supplied to _NewWindow
  1135. *
  1136. * Outputs:    result = zero
  1137. *    carry  = clear
  1138. *
  1139. * External Refs:    NONE
  1140. *
  1141. * Entry Points:    NONE
  1142. *
  1143. *******************************************************************************
  1144.     with RRectDefProcData
  1145.  
  1146. ;
  1147. ; Set the frame bits based on the _NewWindow parmlist settings.
  1148. ;
  1149. ; We only really pay attention to: fClose, fMove.
  1150. ;
  1151. ; In addition, Window manager requires: fVis, fQContent, fCtlTie.
  1152. ;
  1153.  
  1154.     ldy #wFrameBits    ; Get the bits from the parm list.
  1155.     lda [<param],y    ; Make sure we don't affect fAllocated
  1156.     and #$FFFF-fAllocated-fHilited ; or fHilited.
  1157.  
  1158.     ldy #owFrame    ; Get the bits as the WM has them.
  1159.     ora [<theWindow],y    ; Merge his and ours together...
  1160.     sta [<theWindow],y    ; ...and save them.
  1161.  
  1162. ; copy the wRefCon, wContDraw, and wColors from the parmlist
  1163.  
  1164.     ldy #owrRefCon    ; dest index
  1165.     ldx #wRefCon    ; source index
  1166.     lda #8    ; bytes to move
  1167.     jsr CopyBlock
  1168.  
  1169. ; Copy all of the custom stuff into the end of the window record
  1170.  
  1171.     ldy #windSize    ; used as dest index
  1172.     ldx #wCustom    ; used as source index
  1173.     lda #wEnd-wCustom    ; bytes to move
  1174.     jsr CopyBlock
  1175.  
  1176. ; The frame controls are already zeroed out by the Window manager before
  1177. ; we get called, so we don't have to initialize that field.
  1178.  
  1179.  
  1180. ; Finally, calculate the Frame and Content regions
  1181.  
  1182.     jsr rrCalcRgns
  1183.  
  1184.     clc
  1185.     rts
  1186.  
  1187.  
  1188. CopyBlock
  1189.     sta Count
  1190. loop
  1191.     phy    ; save the dest index
  1192.     txy    ; transfer in the source index
  1193.     lda [<param],y    ; get a source word
  1194.     ply    ; retrieve the dest index
  1195.     sta [<theWindow],y    ; save the copy
  1196.     iny    ; bump our indices
  1197.     iny
  1198.     inx
  1199.     inx
  1200.     dec Count    ; are we done?
  1201.     dec Count
  1202.     bne loop    ; no - copy some more
  1203.  
  1204.     rts
  1205.  
  1206. Count    ds.b 2
  1207.  
  1208.     ENDP
  1209.  
  1210.     EJECT
  1211. *******************************************************************************
  1212. *
  1213. rrDispose    PROC
  1214. *
  1215. * Description:    Dispose of any additional fields created by the wNew call,
  1216. *    and tell the Window manager whether or not it should
  1217. *    continue the disposal. If we return FALSE, the Window
  1218. *    Manager will:
  1219. *
  1220. *    - erase the window from the screen
  1221. *    - remove the window from the window list
  1222. *    - free any controls in wControls and wFrameCtls
  1223. *    - free the strucRgn, contRgn, and updateRgn handles
  1224. *    - close the GrafPort
  1225. *    - release the window record if it was allocated
  1226. *      dynamically (see allocate bit in wFrame field)
  1227. *
  1228. *
  1229. * Inputs:    NONE
  1230. *
  1231. * Outputs:    to continue disposal: result = FALSE (zero)
  1232. *    to abort disposal:      result = TRUE  (non-zero)
  1233. *    in either case...      carry  = clear
  1234. *
  1235. * External Refs:    NONE
  1236. *
  1237. * Entry Points:    NONE
  1238. *
  1239. *******************************************************************************
  1240.     with RRectDefProcData
  1241.  
  1242.     clc
  1243.     rts
  1244.     ENDP
  1245.  
  1246.     EJECT
  1247. *******************************************************************************
  1248. *
  1249. rrGetDrag    PROC
  1250. *
  1251. * Description:    Return the address of the routine that will draw the
  1252. *    outline of the window as it is dragged. You can take the
  1253. *    easy way out and return $0000 0000 in 'result'; that will
  1254. *    tell the window manager take care of matters by dragging
  1255. *    the bounds rectangle of the strucRgn. I use my own routine
  1256. *    which draws a RoundRect.
  1257. *
  1258. *
  1259. * Inputs:    NONE
  1260. *
  1261. * Outputs:    result = pointer to Drag routine, $0000 0000 for default
  1262. *
  1263. * External Refs:    NONE
  1264. *
  1265. * Entry Points:    NONE
  1266. *
  1267. *******************************************************************************
  1268.     with RRectDefProcData
  1269.  
  1270.     lda #myDrag    ; return the pointer to my routine
  1271.     sta <result
  1272.     lda #^myDrag
  1273.     sta <result+2
  1274.  
  1275.     jsr GetStrucRect    ; get a copy of the rect to drag
  1276.  
  1277.     lda strucRect    ; make a local copy
  1278.     sta DragRect
  1279.     lda strucRect+2
  1280.     sta DragRect+2
  1281.     lda strucRect+4
  1282.     sta DragRect+4
  1283.     lda strucRect+6
  1284.     sta DragRect+6
  1285.  
  1286.     ldy #xowRV    ; get the radii of the corners
  1287.     lda [<theWindow],y
  1288.     sta localRV
  1289.  
  1290.     ldy #xowRH
  1291.     lda [<theWindow],y
  1292.     sta localRH
  1293.  
  1294.     clc
  1295.     rts
  1296.  
  1297. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1298. ;
  1299. ; This drag routine will be called with the following parameters:
  1300. ;
  1301. ;    PUSH:WORD - delta X (signed)
  1302. ;    PUSH:WORD - delta Y (Your truly,)
  1303. ;    PUSH:BYTE[3] - return address
  1304.  
  1305. RTLAddr    equ 1
  1306. DY    equ RTLAddr+3
  1307. DX    equ DY+2
  1308.  
  1309. myDrag
  1310.     clc    ; offset/copy the original rectangle
  1311.     lda DragRect
  1312.     adc DY,s
  1313.     sta DragRect2
  1314.  
  1315.     clc
  1316.     lda DragRect+2
  1317.     adc DX,s
  1318.     sta DragRect2+2
  1319.  
  1320.     clc
  1321.     lda DragRect+4
  1322.     adc DY,s
  1323.     sta DragRect2+4
  1324.  
  1325.     clc
  1326.     lda DragRect+6
  1327.     adc DX,s
  1328.     sta DragRect2+6
  1329.  
  1330.     pha    ; save the pen mode
  1331.     _GetPenMode
  1332.  
  1333.     PushWord #modeXOR    ; and change it to XOR
  1334.     _SetPenMode
  1335.  
  1336.     PushLong #DragRect2
  1337.     PushWord localRH
  1338.     PushWord localRV
  1339.     _FrameRRect
  1340.  
  1341.     _SetPenMode    ; restore the old pen mode
  1342.  
  1343.     lda RTLAddr,s    ; move the rtl address back up
  1344.     sta 5,s
  1345.     lda RTLAddr+1,s
  1346.     sta 6,s
  1347.  
  1348.     pla    ; remove the parameters
  1349.     pla
  1350.  
  1351.     rtl    ; back to dragrect!
  1352.  
  1353.  
  1354. DragRect    ds.b 8
  1355. DragRect2    ds.b 8
  1356. localRH    ds.b 2
  1357. localRV    ds.b 2
  1358.  
  1359.     ENDP
  1360.  
  1361.     EJECT
  1362. *******************************************************************************
  1363. *
  1364. rrGrowFrame    PROC
  1365. *
  1366. * Description:    Draw the outline of the window frame as it is grown. The
  1367. *    easiest way to deal with this routine is to ignore
  1368. *    everything passed to it, and return $0000 in result. This
  1369. *    will grow windows the normal way.
  1370. *
  1371. *
  1372. * Inputs:    'param' points to the following data structure:
  1373. *
  1374. *        newsize    RECT  Rectangle that defines the new size
  1375. *        drawFlag   WORD  TRUE to draw frame, false to erase
  1376. *        startRect  RECT  Bounds of wStrucRgn when dragging started.
  1377. *        deltaY     WORD  Vertical movement since starting to drag (signed).
  1378. *        deltaX     WORD  Horizontal movement since starting to drag (signed).
  1379. *
  1380. * Outputs:    'result' should have the following bits set or clear:
  1381. *
  1382. *        0: TRUE if frame was drawn by us, FALSE if default frame is requested.
  1383. *        1: TRUE if newSize RECT was changed in a custom fashion, FALSE if not.
  1384. *
  1385. * External Refs:    NONE
  1386. *
  1387. * Entry Points:    NONE
  1388. *
  1389. *******************************************************************************
  1390.     with RRectDefProcData
  1391.  
  1392. newSize     equ 0
  1393. drawFlag    equ newSize+8
  1394. startRect    equ drawFlag+2
  1395. deltaY    equ startRect+8
  1396. deltaX    equ deltaY+2
  1397.  
  1398. ;
  1399. ; param is a pointer to a data block, the first 8 bytes of which
  1400. ; is the rectangle we want to draw. So push Param on the stack for
  1401. ; FrameRRect.
  1402. ;
  1403.     PushLong <param
  1404.     ldy #xowRH
  1405.     PushWord [<theWindow],y
  1406.     ldy #xowRV
  1407.     PushWord [<theWindow],y
  1408.     _FrameRRect
  1409.  
  1410.     lda #%0001    ; say the we drew the rect but
  1411.     sta <result    ; didn't change it.
  1412.  
  1413.     clc
  1414.     rts
  1415.     ENDP
  1416.  
  1417.     EJECT
  1418. *******************************************************************************
  1419. *
  1420. rrRecSize    PROC
  1421. *
  1422. * Description:    Return the size of the window record required by this
  1423. *    defProc. This number is the number of bytes needed beyond
  1424. *    the number normally allocated by the window manager.
  1425. *
  1426. *    If you want to indicate that storage has already been
  1427. *    allocated (perhaps a a field was set in the NewWindow
  1428. *    parameter list, like wStorage in the standard window list),
  1429. *    then return the pointer to that record with bit 31 set.
  1430. *
  1431. *
  1432. * Inputs:    param  = pointer to parameter list supplied to _NewWindow
  1433. *
  1434. * Outputs:    result = number of additional bytes required, or
  1435. *             pointer to window record with the high bit set
  1436. *    carry  = clear
  1437. *
  1438. * External Refs:    NONE
  1439. *
  1440. * Entry Points:    NONE
  1441. *
  1442. *******************************************************************************
  1443.     with RRectDefProcData
  1444.  
  1445. ; Let's see if there is storage defined in the parameter list
  1446.  
  1447.     ldy #wStorage
  1448.     lda [<param],y
  1449.     iny
  1450.     iny
  1451.     ora [<param],y
  1452.     bne Allocated
  1453.  
  1454. ; No, so tell the window manager how large it should be
  1455.  
  1456.     lda #xowEnd-windSize
  1457.     sta <result
  1458.     bra done
  1459.  
  1460. Allocated
  1461.     lda [<param],y    ; Return the high word with the high
  1462.     ora #$8000    ; bit set to tell the WMgr what we did.
  1463.     sta <result+2
  1464.     dey
  1465.     dey
  1466.     lda [<param],y    ; Return the low word normally
  1467.     sta <result
  1468.  
  1469. done
  1470.     clc
  1471.     rts
  1472.     ENDP
  1473.  
  1474.     EJECT
  1475. *******************************************************************************
  1476. *
  1477. rrPosition    PROC
  1478. *
  1479. * Description:    Supply the rectangle to be used as the window's PortRect.
  1480. *
  1481. *
  1482. * Inputs:    param  = pointer to parameter list supplied to _NewWindow
  1483. *
  1484. * Outputs:    result = pointer to the rect to be used as the PortRect
  1485. *    carry  = clear
  1486. *
  1487. * External Refs:
  1488. *
  1489. * Entry Points:
  1490. *
  1491. *******************************************************************************
  1492.     with RRectDefProcData
  1493.  
  1494. ; Take the pointer to the parameter list and add the offset to field
  1495. ; that holds the portrect.
  1496.  
  1497.     ADD4 #wPosition,<param,<result
  1498.  
  1499.     clc
  1500.     rts
  1501.     ENDP
  1502.  
  1503.     EJECT
  1504. *******************************************************************************
  1505. *
  1506. rrBehind    PROC
  1507. *
  1508. * Description:    This routine extracts the wPlane value of the parmList
  1509. *    passed to NewWindow and passes it back to the Window
  1510. *    Manager in 'result'. Pass back $FFFF FFFF to always place
  1511. *    the window on top, or $0000 0000 to place the window on the
  1512. *    bottom.
  1513. *
  1514. *
  1515. * Inputs:    param  = pointer to parameter list passed to _NewWindow
  1516. *
  1517. * Outputs:    result = window pointer, $FFFF FFFF, or $0000 0000
  1518. *    carry  = clear
  1519. *
  1520. * External Refs:    NONE
  1521. *
  1522. * Entry Points:    NONE
  1523. *
  1524. *******************************************************************************
  1525.     with RRectDefProcData
  1526.  
  1527.     ldy #wPlane    ; simply get what was specified in
  1528.     lda [<param],y    ; the parameter list supplied to
  1529.     sta <result    ; _NewWindow (since we are the only
  1530.     iny    ; one who knows where is it) and return
  1531.     iny    ; it to the Window Manager.
  1532.     lda [<param],y
  1533.     sta <result+2
  1534.  
  1535.     clc
  1536.     rts
  1537.     ENDP
  1538.  
  1539.     EJECT
  1540. *******************************************************************************
  1541. *
  1542. rrCallDefProc    PROC
  1543. *
  1544. * Description:    Generic call to the defProc. Through this, the Window
  1545. *    Manager can access the fields in the custom window's
  1546. *    record in response to the many Get/Set calls.
  1547. *
  1548. *
  1549. * Inputs:    On entry, 'param' points to the following block of data:
  1550. *
  1551. *    WORD : dRequest    Requested operation number
  1552. *    WORD : paramID    Parameter block type:
  1553. *            $0000-7FFF reserved by system
  1554. *            $8000-FFFF reserved for application
  1555. *          (We only handle type $0000 System
  1556. *           in this sample)
  1557. *    XXXX : newParam    Operation specific data
  1558. *
  1559. * Outputs:    Call specific. See technote for more details.
  1560. *
  1561. * External Refs:
  1562.     import rrSetTitle
  1563.     import rrSetColor
  1564.     import rrSetFrame
  1565.     import rrGetTitle
  1566.     import rrGetColor
  1567.     import rrGetFrame
  1568.     import handleWTask
  1569. *
  1570. * Entry Points:    NONE
  1571. *
  1572. *******************************************************************************
  1573.     with RRectDefProcData
  1574.  
  1575. dRequest    equ 0
  1576. paramID    equ dRequest+2
  1577. newParam    equ paramID+2
  1578.  
  1579. MaxDRequest    equ 33
  1580.  
  1581.     ldy #paramID    ; Do we know this paramID type?
  1582.     lda [<param],y
  1583.     bne ignore    ; $0000, ignore all others
  1584.  
  1585.     lda [<param]    ; dRequest
  1586.     cmp #MaxDRequest+1    ; is this request in range?
  1587.     bcs ignore    ; no so leave
  1588.     asl a    ; yes, turn into index into proc table
  1589.     tax
  1590.     jmp (dRequestTable,x)
  1591.  
  1592. dRequestTable
  1593.     dc.w ignore    ;  0 wSetOrgmask
  1594.     dc.w ignore    ;  1 wSetMaxGrow
  1595.     dc.w ignore    ;  2 wSetScroll
  1596.     dc.w ignore    ;  3 wSetPage
  1597.     dc.w ignore    ;  4 wSetInfoRefCon
  1598.     dc.w ignore    ;  5 wSetInfoDraw
  1599.     dc.w ignore    ;  6 wSetOrigin
  1600.     dc.w ignore    ;  7 wSetDataSize
  1601.     dc.w ignore    ;  8 wSetZoomRect
  1602.     dc.w rrSetTitle    ;  9 wSetTitle
  1603.     dc.w rrSetColor    ; 10 wSetColorTable
  1604.     dc.w rrSetFrame    ; 11 wSetFrameFlag
  1605.     dc.w ignore    ; 12 wGetOrgMask
  1606.     dc.w ignore    ; 13 wGetMaxGrow
  1607.     dc.w ignore    ; 14 wGetScroll
  1608.     dc.w ignore    ; 15 wGetPage
  1609.     dc.w ignore    ; 16 wGetInfoRefCon
  1610.     dc.w ignore    ; 17 wGetInfoDraw
  1611.     dc.w ignore    ; 18 wGetOrigin
  1612.     dc.w ignore    ; 19 wGetDataSize
  1613.     dc.w ignore    ; 20 wGetZoomRect
  1614.     dc.w rrGetTitle    ; 21 wGetTitle
  1615.     dc.w rrGetColor    ; 22 wGetColorTable
  1616.     dc.w rrGetFrame    ; 23 wGetFrameFlag
  1617.     dc.w ignore    ; 24 wGetInfoRect
  1618.     dc.w ignore    ; 25 wGetDrawInfo
  1619.     dc.w ignore    ; 26 wGetStartInfoDraw
  1620.     dc.w ignore    ; 27 wGetEndInfoDraw
  1621.     dc.w ignore    ; 28 wZoomWindow
  1622.     dc.w ignore    ; 29 wStartDrawing
  1623.     dc.w rrStartMove    ; 30 wStartMove (defined in this PROC)
  1624.     dc.w ignore    ; 31 wStartGrow
  1625.     dc.w rrNewSize    ; 32 wNewSize (defined in this PROC)
  1626.     dc.w handleWTask    ; 33 wTask
  1627.  
  1628. rrStartMove    ldy #newParam+2    ; Preparing to move the window. Examine
  1629.     lda [<param],y    ; the proposed destination rectangle
  1630.     sta <result+2    ; and see if it is OK. If it is, simply
  1631.     dey    ; return it. If it isn't, then change
  1632.     dey    ; it. We will like it, so we'll just
  1633.     lda [<param],y    ; return what we get.
  1634.     sta <result
  1635.     clc
  1636.     rts
  1637.  
  1638. rrNewSize
  1639.     lda #1    ; Always return TRUE. This tells the
  1640.     sta <result    ; window manager to redraw only
  1641.     clc    ; uncovered contents.
  1642.     rts
  1643.  
  1644. ignore    clc
  1645.     rts
  1646.  
  1647.     ENDP
  1648.  
  1649.     EJECT
  1650. *******************************************************************************
  1651. *
  1652. handleWTask    PROC
  1653. *
  1654. * Description:    Called to handle FindWindow results passed on by
  1655. *    TaskMaster. Since TaskMaster only handles event that occur
  1656. *    in menus and system windows, custom window defprocs must
  1657. *    handle all of the rest. These include:
  1658. *
  1659. *    wInContent    wInDrag
  1660. *    wInGrow    wInGoAway
  1661. *    wInZoom    wInInfo
  1662. *    wInFrame
  1663. *
  1664. *
  1665. * Inputs:    'param' points to the following block of data:
  1666. *
  1667. *    WORD:dRequest    = 33 for wTask
  1668. *    WORD:paramID    we only handle type $0000 System calls
  1669. *    LONG:newParam    Pointer to Task Record
  1670. *    WORD:newParam    result from FindWindow
  1671. *
  1672. * Outputs:    'result' equals the following:
  1673. *
  1674. *        Low Word    High Word
  1675. *        -----------------    -------------------
  1676. *    If the event was handled:    Zero    Action taken
  1677. *    If the event was not handled:    FindWindow result    ignored
  1678. *
  1679. * External Refs:    NONE
  1680. *
  1681. * Entry Points:    NONE
  1682. *
  1683. *******************************************************************************
  1684.     with RRectDefProcData
  1685.  
  1686. dRequest    equ 0
  1687. paramID    equ dRequest+2
  1688. newParam    equ paramID+2
  1689. TaskRecPtr    equ newParam
  1690. FWResult    equ TaskRecPtr+4
  1691.  
  1692. TaskRec    equ work
  1693.  
  1694.     ldy #TaskRecPtr+2    ; get the pointer to the Event Record
  1695.     lda [<param],y    ; into 'TaskRec', aka 'work'.
  1696.     sta <TaskRec+2
  1697.     dey
  1698.     dey
  1699.     lda [<param],y
  1700.     sta <TaskRec
  1701.  
  1702.     ldy #FWResult    ; get the Findwindow result
  1703.     lda [<param],y
  1704.  
  1705.     sec    ; turn it into an index
  1706.     sbc #wInContent
  1707.     bcc callIgnore    ; out of range, so ignore
  1708.     cmp #wInFrame-wInContent+1
  1709.     bcc doit
  1710. callIgnore    lda #wInSpecial-wInContent+1
  1711. doit    asl a
  1712.     tax
  1713.     jmp (wTaskTable,x)
  1714.  
  1715. wTaskTable    dc.w doInContent    ; doInContent
  1716.     dc.w doInDrag    ; doInDrag
  1717.     dc.w ignoreTask    ; doInGrow
  1718.     dc.w doInGoAway    ; doInGoAway
  1719.     dc.w ignoreTask    ; doInZoom
  1720.     dc.w ignoreTask    ; doInInfo
  1721.     dc.w ignoreTask    ; doInSpecial (default ignore)
  1722.     dc.w ignoreTask    ; doInDeskItem (not used)
  1723.     dc.w doInContent    ; doInFrame
  1724.  
  1725. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1726. ;
  1727. ; TaskMaster needs us to handle a wInContent event. Check the TaskMask
  1728. ; field to see if the application wants us to handle it. If so, bring the
  1729. ; window to front. Then check to see if the application wants to know what
  1730. ; we just did. If so, return wInContent. If not, return null.
  1731.  
  1732. doInContent
  1733.     ldy #owmTaskMask    ; do we handle clicks in the content?
  1734.     lda [<TaskRec],y
  1735.     and #tmContent
  1736.     bne Bogus0010    ; yes - just select the window
  1737.     brl ignoreTask    ; no - so pretend we weren't here.
  1738.  
  1739. Bogus0010    jsr mySelectWindow
  1740.  
  1741.     ldy #owFrame    ; do we tell the app what we did?
  1742.     lda [<theWindow],y
  1743.     and #fQContent
  1744.     beq Passively    ; no - just return a nullEvt
  1745.  
  1746.     ldx #0
  1747.     lda #wInContent    ; pass this on to the application
  1748.     brl Exit
  1749. Passively
  1750.     ldx #wInContent    ; This is what we did.
  1751.     lda #0    ; Signal that event was handled
  1752.     brl Exit
  1753.  
  1754. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1755. ;
  1756. ; TaskMaster needs us to handle a wInDrag event. Check the TaskMask
  1757. ; field to see if the application wants us to handle it. If so, call
  1758. ; DragWindow with the same parameters described in the TaskMaster
  1759. ; psuedo-code in the ToolBox Reference. Then check to see if the Apple
  1760. ; key was down. If it wasn't, bring the window forward. Finally, return
  1761. ; null.
  1762. ;
  1763. doInDrag
  1764.     ldy #owmTaskMask    ; do we do drags?
  1765.     lda [<TaskRec],y
  1766.     and #tmDragW
  1767.     bne Bogus0020    ; yes - get on with it.
  1768.     brl ignoreTask    ; no - so pretend we weren't here.
  1769. Bogus0020
  1770.     PushWord #0    ; drag resolution
  1771.     ldy #owhere+2    ; global coord of cursor
  1772.     PushWord [<TaskRec],y ; first X
  1773.     dey
  1774.     dey
  1775.     PushWord [<TaskRec],y ; then Y
  1776.     PushWord #8    ; grace buffer around bounds
  1777.     PushLong #0    ; default cursor boundary
  1778.     ldy #owmTaskData+2    ; push on window's grafport
  1779.     PushWord [<TaskRec],y
  1780.     dey
  1781.     dey
  1782.     PushWord [<TaskRec],y
  1783.     _DragWindow    ; Call DrawWindow ourselves
  1784.  
  1785.     ldy #omodifiers    ; if the Apple Key is down then
  1786.     lda [<TaskRec],y    ; don't bring the window to front
  1787.     and #appleKey
  1788.     bne doneDrag
  1789.  
  1790.     jsr mySelectWindow
  1791. doneDrag
  1792.     ldx #wInDrag    ; This is what we did.
  1793.     lda #0    ; Signal that event was handled
  1794.     bra Exit    ; Exit the DefProc
  1795.  
  1796. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1797. ;
  1798. ; TaskMaster needs us to handle a wInGoAway event. Check the TaskMask
  1799. ; field to see if the application wants us to handle it. If so, call
  1800. ; TrackGoAway. If it returns TRUE, then return wInGoAway to the
  1801. ; application. If it returns FALSE, return wNoHit.
  1802. ;
  1803. doInGoAway
  1804.     pha    ; space for boolean result
  1805.     ldy #owhere+2    ; global coord of cursor
  1806.     PushWord [<TaskRec],y ; first X
  1807.     dey
  1808.     dey
  1809.     PushWord [<TaskRec],y ; then Y
  1810.     ldy #owmTaskData+2    ; push on window's grafport
  1811.     PushWord [<TaskRec],y
  1812.     dey
  1813.     dey
  1814.     PushWord [<TaskRec],y
  1815.     _TrackGoAway
  1816.     pla
  1817.     beq noClose
  1818.  
  1819.     ldx #0    ; Close selected. Tell app that we
  1820.     lda #wInGoAway    ; clicked in the goAway box.
  1821.     bra Exit
  1822. noClose
  1823.     ldx #wInGoAway    ; Close not selected. Tell the app that
  1824.     lda #wNoHit    ; we tracked it, but that everything is
  1825.     bra Exit    ; OK now.
  1826.  
  1827.  
  1828. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1829. ;
  1830. ; Local routine to bring the window forward if we need to.
  1831. ;
  1832. mySelectWindow
  1833.     lda <theWindow    ; get the pointer to the window so that
  1834.     clc    ; we can  bring it to front.
  1835.     adc #4
  1836.     tax
  1837.     lda <theWindow+2
  1838.     pha
  1839.     phx
  1840.     _SelectWindow
  1841.     rts
  1842.  
  1843.  
  1844. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1845. ;
  1846. ; For some reason, we need to ignore a task. Either we were asked to handle
  1847. ; an event we know nothing about, or the TaskMask prohibited us from 
  1848. ; handling a certain event. This routine simply echos the result found by
  1849. ; FindWindow back to the application.
  1850.  
  1851. ignoreTask    ldy #FWResult    ; ignore by echoing the FindWindow
  1852.     lda [<param],y    ;   result.
  1853.     ldx #0    ; fall through to Exit.
  1854.  
  1855. Exit
  1856.     sta <result    ; TaskMaster result on the stack
  1857.     stx <result+2    ; Low word of TaskData
  1858.  
  1859.     clc
  1860.     rts
  1861.     endp
  1862.  
  1863.     EJECT
  1864. *******************************************************************************
  1865. *
  1866. HouseKeeping    PROC
  1867. *
  1868. * Description:    Housekeeping calls. Set and get various fields. These will
  1869. *    redraw the window if necessary.
  1870. *
  1871. *
  1872. * Inputs:
  1873. *
  1874. * Outputs:
  1875. *
  1876. * External Refs:
  1877.     import drawFrame
  1878. *
  1879. * Entry Points:
  1880.     entry rrSetTitle
  1881.     entry rrSetColor
  1882.     entry rrSetFrame
  1883.     entry rrGetTitle
  1884.     entry rrGetColor
  1885.     entry rrGetFrame
  1886. *
  1887. *******************************************************************************
  1888.     with RRectDefProcData
  1889.  
  1890. dRequest    equ 0
  1891. paramID    equ dRequest+2
  1892. newParam    equ paramID+2
  1893.  
  1894.  
  1895. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1896.  
  1897. rrSetTitle    ldy #xowTitle+2
  1898.     bra SetLong
  1899.  
  1900. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1901.  
  1902. rrSetColor    ldy #xowColorPtr+2
  1903.     bra SetLong
  1904.  
  1905. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1906.  
  1907. rrSetFrame    ldy #owFrame
  1908.     bra SetWord
  1909.  
  1910. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1911.  
  1912. rrGetTitle    ldy #xowTitle+2
  1913.     bra GetLong
  1914.  
  1915. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1916.  
  1917. rrGetColor    ldy #xowColorPtr+2
  1918.     bra GetLong
  1919.  
  1920. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1921.  
  1922. rrGetFrame    ldy #xowColorPtr
  1923.     bra GetWord
  1924.  
  1925. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1926.  
  1927. SetLong
  1928.     phy
  1929.     ldy #newParam+2
  1930.     lda [<param],y
  1931.     ply
  1932.     sta [<theWindow],y
  1933.     dey
  1934.     dey
  1935. SetWord    phy
  1936.     lda #newParam
  1937.     lda [<param],y
  1938.     ply
  1939.     sta [<theWindow],y
  1940.  
  1941.     lda <theWindow    ; Now redraw the window frame
  1942.     clc
  1943.     adc #4
  1944.     tax
  1945.     lda <theWindow+2
  1946.     pha
  1947.     phx
  1948.     _StartFrameDrawing    ; must be called by defproc
  1949.  
  1950.     jsr drawFrame
  1951.  
  1952.     _EndFrameDrawing    ; reverses StartFrameDrawing call
  1953.  
  1954.     clc
  1955.     rts
  1956.  
  1957. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1958. ;
  1959. ; Called by the rrGetxxxxx routines above. Enter with Y holding the
  1960. ; offset to a LONG parameter in the window record. This routine will
  1961. ; fetch that value and put it into 'result'.
  1962. ;
  1963.  
  1964. GetLong
  1965.     lda [<theWindow],y
  1966.     sta <result+2
  1967.     dey
  1968.     dey
  1969. GetWord    lda [<theWindow],y
  1970.     sta <result
  1971.     clc
  1972.     rts
  1973.     ENDP